<?php
/*
 * MiniMe - a minimalistic OStatus complient microblogging tool
 * Copyright (C) 2010, Tuomas Koski - koski.tuomas@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @author     Tuomas Koski <koski.tuomas@gmail.com>
 * @copyright  Tuomas Koski
 * @license    http://www.gnu.org/licenses/lgpl.txt
 */
class Controller_Pubsubhubbub_Hub extends Controller_Abstract implements Controller_Interface {
    
    public function __construct($getParams, $postParams, $phpInput, $conf) {

        parent::__construct($getParams, $postParams, $phpInput, $conf);
        
    }
    
    //TODO rework this. It's now just a "proof of concept".
    public function execute() {
    
        file_put_contents ("/tmp/minime-hub.input", print_r(apache_request_headers(), true) . "\nPOST:\n" . print_r($_POST, true) . "\nGET:\n" . print_r($_GET, true) . "\nRAW:\n" . $this->phpInput);

        // http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#verifysub
        $req['callback']      = trim($_POST['hub_callback']);
        $req['mode']          = trim($_POST['hub_mode']);
        $req['topic']         = trim($_POST['hub_topic']);
        $req['verify']        = trim($_POST['hub_verify']);
        $req['verify_token']  = trim($_POST['hub_verify_token']); // bug here, this is not mandatory!
        $req['lease_seconds'] = trim($_POST['hub_lease_seconds']); // bug here, this is not mandatory!
        $req['secret']        = trim($_POST['hub_secret']); // bug here, this is not mandatory!
        
        if(empty($req['callback']) ||
           empty($req['mode']) ||
           empty($req['topic']) ||
           empty($req['verify_token']) ||
           ($req['mode'] != "subscribe" && $req['mode'] != "unsubscribe") ) {
        
                $this->headers[400] = "HTTP/1.1 400 Bad Request";
                $this->output = "HTTP/1.1 400 Bad Request - Subscription/unsubscription paramaters are just wrong. " . print_r($_POST, true);
                file_put_contents ("/tmp/minime-hub.output",$this->output); 
                return;
        }
        
        // Let's verify the request.
        $challenge = md5($req['topic'] . $req['callback']);
        $verifyParams = array('hub.mode'          => $req['mode'],
                              'hub.topic'         => $req['topic'],
                              'hub.challenge'     => $challenge,
                              'hub.verify_token'  => $req['verify_token']);
        
        if(!empty($req['lease_seconds'])) {
            $verifyParams['hub.lease_seconds'] = $req['lease_seconds'];
        }
        
        if(strpos($req['callback'], '?') === false) {
            $verify_url = $req['callback'] . '?' . http_build_query($verifyParams);
        } else {
            $verify_url = $req['callback'] . '&' . http_build_query($verifyParams);
        }
        
        // TODO Change this to curl!
        $ctx = stream_context_create(array(
            'http' => array(
                    'method'=>'GET',
                    'timeout' => 3
                    )
            )
        );
        $uc = @file_get_contents($verify_url, 0, $ctx);
        
        if(!isset($http_response_header[0])) {
            $this->headers[400] = "HTTP/1.1 400 Bad Request";
            $this->output = "HTTP/1.1 400 Bad Request - Subscribing callback URL [" . $verify_url . "] did not reply correclty to verification.";
            file_put_contents ("/tmp/minime-hub.output",$this->output);
            return;
        }
        
        list($version,$status_code,$msg) = explode(' ', $http_response_header[0]);
        
        if(trim($uc) != $challenge) {
            $this->headers[400] = "HTTP/1.1 400 Bad Request";
            $this->output = "HTTP/1.1 400 Bad Request - wrong result for the verification request. Challenge sent '" . $challenge . "', received '" . $uc . "'.";
            file_put_contents ("/tmp/minime-hub.output",$this->output);
            return;
        }
        
        if($req['mode'] == "subscribe") {
        
            if(empty($req['lease_seconds'])) {
                $req['lease_seconds'] = 60*60*24*7; // one week.
            }
        
            $this->headers[204] = 'HTTP/1.1 204 No Content';

            $array['callback'] = $req['callback'];
            $array['topic'] = $req['topic'];
            $array['lease_seconds'] = $req['lease_seconds'];
            $array['secret'] = $req['secret'];
            $array['verify_token'] = $req['verify_token'];
            $array['title'] = "Suscriber request on " . date('c');
            $array['subid'] = md5($req['callback']);
            
            $loader = new Minime_Pubsubhubbub_Subscribers_Loader($this->conf);
            
            $subid = Pubsubhubbub_Subscribe::createID($req['topic']);
            $subs = $loader->getSubscribers($subid);
            if(!$subs) {
                $subs = new Minime_Pubsubhubbub_Subscribers();
            }
            $subs->addSubscriber(Minime_Pubsubhubbub_Subscriber::buildFromArray($array));
            
            $storer = new Minime_Pubsubhubbub_Subscribers_Storer($this->conf);
            $storer->stroreSubscribers($subid, $subs->asXml());
            file_put_contents ("/tmp/minime-hub.output","All OK.");
        } elseif ($req['mode'] == "unsubscribe") {
            $this->headers[204] = "HTTP/1.1 204 No Content'";
            
            $loader = new Minime_Pubsubhubbub_Subscribers_Loader($this->conf);
            
            $subid = Pubsubhubbub_Subscribe::createID($req['topic']);
            $subscriber_id = md5($req['callback']);
            
            $subs = $loader->getSubscribers($subid);
            if(!empty($subs)) {
                $subs->removeSubscriber($subscriber_id);
            
                $storer = new Minime_Pubsubhubbub_Subscribers_Storer($this->conf);
                $storer->stroreSubscribers($subid, $subs->asXml());
            }
            
            file_put_contents ("/tmp/minime-hub.output","All OK in unsubscribe.");
        } else {
            $this->headers[501] = "HTTP/1.1 501 Not Found";
            $this->output = "Something went just wrong. Please contact support. Hmm it doesn ot exists yet so just contact koski.tuomas@gmail.com.";
            file_put_contents ("/tmp/minime-hub.output",$this->output);
        }
    }
}
